package JavaEE.MySQL;
/*
* 索引的相关操作
* 1.查看索引 show index from 表名;
* 2.创建索引 create index 索引名 on 表名(列名);
* 3.删除索引 drop index 索引名 on 表名;
* (primary key(主键),foreign key(外键),unique(唯一))都会自动生成索引
*
*
* 1.例:
* create table class(id int primary key,name varchar(20));
* create table student(
* id int primary key,
* name varchar(20),
* classId int,
* foreign key(classId) references class(id));
* (以classId作为外键,与class的id进行表链接)
* 那么show index from class -> 查询出一个索引,id
*    show index from student -> 查询出两个索引,id,classId
*
* 2.例:
* 上述的student表中已经存在了两个索引,那么我们可以让name也成为索引(手动)
* create index idx_name on student(name);
* (注:创建索引操作,是个危险操作!!!,所以最好创建表时就规划好)
*
* 3.例:
* 此时student表中存在了三个索引,此时我们也可以删除索引
* drop index idx_name in student1; (成功)
* drop index classId in student1; (失败)
* (这是因为,自动创建的索引无法被删除!!!)
*
* MySQL事务的ACID特性:
* A(Atomicity):原子性:
* 一组SQL要么全部成功,要么全部失败,如果过程中出现错误,则回滚到事务开始状态,否则则落盘
* C(Consistency):一致性:
* 事务开始之前和事务结束以后,数据库的完整性不会被破坏.表示(写入的数据必须完全符合所有的预设规则,
* 包括数据的精度,关联性,以及关于事务执行过程中服务器崩溃后如何恢复.)
* I(Isolation):隔离性:
* 多个事务之间不能相互影响
* D(Durability):持久性:
* 对数据的修改永久性的写入存储介质
*
* (以转账为例,张三-100,李四+100)
* 1.要么全部成功,要么全部失败
* 2.转账前后数据一致
* 3.对数据的修改应当落盘(保存到磁盘),持久化
* 4.把不同的操作隔离开
*
* (需要注意的是,每个修改操作,如"插入","更新","删除"本质上就是一句事务)
* 查看当前事务是否自动提交:
* show variables like 'autocommit';
* 可以手动设置成"OFF"关闭:
* set autocommit = 1(自动)/0(手动)
*
*
* 通过以下语句可以完成对事务的控制:
* 开始一个新的事务:
* Start Transaction 或 BEGIN
* 提交当前事务,并对更改持久化保存:
* Commit;
* 回滚当前事务,取消其更改:
* Rollback;
*
* 示例练习:
* 1.开启事务:
* start transaction;
* 2.修改数据:(转账,初始都为1000)
* update bank_account set balance = balance - 100 where id = 1;
* update bank_account set balance = balance + 100 where id = 2;
* 此时 id=1 的用户,账户上为900, id=2 的用户,账户上为1100
* 3.提交事务:(代表确认更改,不能再返回了)
* commit;
* 4.回滚事务:(代表结束事务.如果替换成第3步,则取消两次修改,账户仍都为1000)
* rollback;
*
* 事务的保存点:
* 使回滚时,可以回滚到任意的保存点(类似游戏存档)
* 设置保存点:
* savepoint savepoint1;
* 回滚到保存点:
* rollback to savepoint1;
*
* 示例练习:
* 1.开启事务
* start transaction
* 2.修改数据(账户变为全1000)
* update bank_account set balance = balance + 100 where id = 1;
* update bank_account set balance = balance - 100 where id = 2;
* 3.设置保存点1:
* savepoint sp1;
* 4.插入元素(3,王五,5000):
* insert into bank_account values(3,'王五',5000);
* 5.设置保存点2:
* savepoint sp2;
* 6.删除数据(删除1,张三,1000):
* delete from bank_account where id = 1;
* 7.设置保存点3:
* savepoint sp3;
* 8.回滚到sp2:
* rollback to sp2;(张三回来了)
* 9.回滚到sp1:
* rollback to sp1;(王五走了)
* 10.直接回滚:
* rollback(回到事务刚开始,之前的步骤2也无效)
*
* 事务的隔离级别
* 事务具有隔离性,不同的隔离级别在(性能)和(安全)方面做了取舍:
*  安 | read uncommitted(读未提交) ↑
*  全 | read committed(读已提交)   | 性
*  性 | repeatable read(可重复读)  | 能
*     ↓ serializable(串行化）      |
*
* read uncommitted(读未提交):"事务A可以读到事务B中(未提交)操作后的数据"
* 场景:临近期末考试,我从学长要到了历年常用的题库,当我背完题后,
*     教研组决定今年重新出题,导致考试时,我发现我背的题库根本没出!
* (对应到事务中,事务A对数据进行了修改,事务B可以访问到,但当事务B访问到了
* 事务A还没有提交的数据(就可能回滚,不安全),这个现象叫做"脏读")
*
* read committed(读已提交):"事务A只能读到事务B中(提交)操作后的数据"
* 场景:吸取了上次的教训,直接从教研组的老师手里拿题,教研组有多个版本试卷,每次只能拿到最新装订版本
* (事务A第一次查询某条数据得到了结果a,事务B对这条记录进行了修改并"提交"事务,
* 当事务A再去查询这条数据的时候,发现与第一次查到的内容(结果a)不一致,这个现象叫"不可重复读")
*
* repeatable read(可重复读)"默认":"事务A读到某条信息(未用完),其他事务要等A用完才能修改"
* 场景:上次虽然不错,但万一改版,我又要重新背!这次直接从校长手里拿题!校长要改题,得等我考完!
*     但是校长仍然可以对其他院系的考卷进行修改~
* (事务A第一次查询到的"结果集",与第二次查询到的结果集不一致,这个现象叫"幻读")
* (在Innodb存储引擎中,使用了next-key锁,锁住了目标行之前的间隙,有效解决"大部分"幻读)
*
* serializable(串行化):"所有事物一个接一个执行,能彻底解决数据安全问题"(效率低,单线程)
* 场景:我直接当校长!但是所有事情都要经过我处理(我是单线程),虽然一切皆如我意,但效率低.
*
* 查看和设置隔离级别:
* 事物的隔离级别分为(全局作用域)和(会话作用域),查看不同作用域事务的隔离级别,以下方法:
* 全局作用域:select @@global.transaction_isolation;
* 会话作用域:select @@session.transaction_isolation;
*
*
 */
public class Demo2 {
}
